const app = (typeof getApp === "function") ? getApp() : null;

const MAX_PREVIEW_ITEMS = 3;

const STRINGS = {
  nicknamePlaceholder: "\u672a\u8bbe\u7f6e\u6635\u79f0",
  unnamedActivity: "\u672a\u547d\u540d\u6d3b\u52a8",
  defaultTagline: "\u70ed\u7231\u751f\u6d3b\uff0c\u559c\u6b22\u53c2\u4e0e\u5404\u79cd\u6709\u8da3\u7684\u6d3b\u52a8",
  participatedTitle: "\u6211\u53c2\u4e0e\u7684\u6d3b\u52a8",
  organizedTitle: "\u6211\u53d1\u8d77\u7684\u6d3b\u52a8",
  viewMore: "\u67e5\u770b\u5168\u90e8",
  emptyParticipated: "\u6682\u65e0\u53c2\u4e0e\u7684\u6d3b\u52a8",
  emptyOrganized: "\u6682\u65e0\u53d1\u8d77\u7684\u6d3b\u52a8",
  locationUnknown: "\u5730\u70b9\u5f85\u5b9a",
  timePending: "\u65f6\u95f4\u5f85\u5b9a",
  toastNavigateFailed: "\u8df3\u8f6c\u5931\u8d25",
  toastProfileFailed: "\u65e0\u6cd5\u67e5\u770b",
  settingsTitle: "\u8bbe\u7f6e",
  privacyPolicy: "\u9690\u79c1\u653f\u7b56",
  privacyGuideSubtitle: "\u67e5\u770b\u9690\u79c1\u4fdd\u62a4\u6307\u5f15"
};

const callCloud = options => {
  if (app && typeof app.callCloudFunction === "function") {
    return app.callCloudFunction(options);
  }
  const { loadingTitle, ...rest } = options || {};
  const title =
    typeof loadingTitle === "string" && loadingTitle.trim()
      ? loadingTitle.trim()
      : "加载中...";
  wx.showLoading({ title, mask: true });
  const originalComplete = rest.complete;
  rest.complete = (...args) => {
    wx.hideLoading();
    if (typeof originalComplete === "function") {
      originalComplete(...args);
    }
  };
  return wx.cloud.callFunction(rest);
};

Page({
  data: {
    profile: {
      nickname: "",
      studentID: "",
      avatarSrc: "",
      avatarInitial: "",
      tagline: STRINGS.defaultTagline
    },
    stateTexts: {
      loading: "\u6b63\u5728\u52a0\u8f7d..."
    },
    participatedPreview: [],
    organizedPreview: [],
    loadingParticipated: false,
    loadingOrganized: false,
    labels: {
      participatedTitle: STRINGS.participatedTitle,
      organizedTitle: STRINGS.organizedTitle,
      viewMore: STRINGS.viewMore,
      emptyParticipated: STRINGS.emptyParticipated,
      emptyOrganized: STRINGS.emptyOrganized,
      settingsTitle: STRINGS.settingsTitle
    },
    settings: [
      {
        key: "privacyPolicy",
        title: STRINGS.privacyPolicy,
        description: STRINGS.privacyGuideSubtitle
      }
    ]
  },

  onLoad() {
    this.activityImageCache = {};
    this.refreshProfile();
    this.refreshPreviews();
  },

  onShow() {
    this.refreshProfile();
    this.refreshPreviews();
  },

  onPullDownRefresh() {
    Promise.all([this.refreshProfile(), this.refreshPreviews()])
      .finally(() => {
        wx.stopPullDownRefresh();
      });
  },

  refreshProfile() {
    const user = app && app.globalData && app.globalData.userInfo;
    if (!user) {
      return Promise.resolve();
    }

    const nickname = user.nickname || "";
    const avatar = user.avatar || "";
    const studentID = user.studentID || "";
    const tagline = this.buildTagline(user);

    this.setData({
      profile: Object.assign({}, this.data.profile, {
        nickname: nickname || STRINGS.nicknamePlaceholder,
        studentID,
        avatarInitial: this.computeAvatarInitial(nickname),
        tagline
      })
    });

    return this.resolveAvatar(avatar);
  },

  refreshPreviews() {
    return Promise.all([
      this.fetchParticipatedPreview(),
      this.fetchOrganizedPreview()
    ]);
  },

  fetchParticipatedPreview() {
    this.setData({ loadingParticipated: true });
    return this.callActivityFunction("queryRegisteredActivities")
      .then(list => {
        const resolved = list.slice(0, MAX_PREVIEW_ITEMS);
        this.setData({
          participatedPreview: resolved,
          loadingParticipated: false
        });
      })
      .catch(() => {
        this.setData({
          participatedPreview: [],
          loadingParticipated: false
        });
      });
  },

  fetchOrganizedPreview() {
    this.setData({ loadingOrganized: true });
    return this.callActivityFunction("queryPublishedActivities", {
      //status: "Published"
      tableNumber:1
    })
      .then(list => {
        const resolved = list.slice(0, MAX_PREVIEW_ITEMS);
        this.setData({
          organizedPreview: resolved,
          loadingOrganized: false
        });
      })
      .catch(() => {
        this.setData({
          organizedPreview: [],
          loadingOrganized: false
        });
      });
  },

  callActivityFunction(functionName, extraData = {}) {
    return new Promise((resolve, reject) => {
      callCloud({
        name: functionName,
        data: Object.assign({ tableNumber: 1 }, extraData),
        loadingTitle: "加载中...",
        success: res => {
          const normalized = this.normalizeActivities(res);
          this.resolveActivityImages(normalized)
            .then(list => resolve(list))
            .catch(() => resolve(normalized));
        },
        fail: err => {
          console.error(`${functionName} failed`, err);
          reject(err);
        }
      });
    });
  },

  normalizeActivities(response) {
    const payload =
      (response && response.result) ? response.result : (response || {});
    const list = Array.isArray(payload.activities)
      ? payload.activities
      : [];

    return list.map(item => {
      const activity = item || {};
      const times = this.extractStartTimes(activity);
      return {
        activityID: activity.activityID || "",
        activityName: activity.activityName || STRINGS.unnamedActivity,
        activityImage: activity.activityImage || "",
        activityLocation: activity.activityLocation || STRINGS.locationUnknown,
        timeText: this.buildTimeText(times)
      };
    });
  },

  extractStartTimes(activity) {
    const times = [];
    if (Array.isArray(activity.activityTime)) {
      activity.activityTime.forEach(entry => {
        if (entry && entry.startTime) {
          times.push(entry.startTime);
        }
      });
    }
    if (Array.isArray(activity.activityStartTime)) {
      activity.activityStartTime.forEach(entry => {
        if (entry) {
          times.push(entry.startTime || entry);
        }
      });
    }
    return times;
  },

  buildTimeText(times) {
    if (!Array.isArray(times) || times.length === 0) {
      return STRINGS.timePending;
    }

    const formatted = times
      .map(time => this.formatDateTime(time))
      .filter(Boolean);

    if (formatted.length === 0) {
      return STRINGS.timePending;
    }

    return formatted[0];
  },

  formatDateTime(value) {
    if (!value) return "";
    const date = value instanceof Date ? value : new Date(value);
    if (Number.isNaN(date.getTime())) {
      return typeof value === "string" ? value : "";
    }
    const month = date.getMonth() + 1;
    const day = date.getDate();
    return `${month}\u6708${day}\u65e5`;
  },

  resolveActivityImages(activities) {
    if (!Array.isArray(activities) || activities.length === 0) {
      return Promise.resolve([]);
    }

    const cache = this.activityImageCache || (this.activityImageCache = {});
    const toFetch = [];

    activities.forEach(activity => {
      const image = activity && activity.activityImage;
      if (
        typeof image === "string" &&
        image.indexOf("cloud://") === 0 &&
        !cache[image]
      ) {
        toFetch.push(image);
      }
    });

    if (toFetch.length === 0) {
      return Promise.resolve(
        activities.map(activity => this.applyImageCache(activity))
      );
    }

    return wx.cloud
      .getTempFileURL({ fileList: Array.from(new Set(toFetch)) })
      .then(res => {
        const list = (res && res.fileList) || [];
        list.forEach(file => {
          if (file.status === 0 && file.tempFileURL) {
            cache[file.fileID] = file.tempFileURL;
          }
        });
        return activities.map(activity => this.applyImageCache(activity));
      })
      .catch(err => {
        console.error("resolveActivityImages failed", err);
        return activities;
      });
  },

  applyImageCache(activity) {
    if (!activity) return activity;
    const cache = this.activityImageCache || {};
    const image = activity.activityImage;
    if (typeof image === "string" && cache[image]) {
      return Object.assign({}, activity, { activityImage: cache[image] });
    }
    return activity;
  },

  buildTagline(user) {
    if (!user) return STRINGS.defaultTagline;
    const parts = [];
    if (user.college) parts.push(user.college);
    if (user.major) parts.push(user.major);
    if (parts.length === 0 && user.nickname) parts.push(user.nickname);
    if (parts.length === 0) return STRINGS.defaultTagline;
    return parts.join(" · ");
  },

  computeAvatarInitial(name) {
    if (!name) return "";
    const value = String(name).trim();
    if (!value) return "";
    const first = value.charAt(0);
    if (/^[a-zA-Z]$/.test(first)) return first.toUpperCase();
    return first;
  },

  resolveAvatar(avatar) {
    if (!avatar) {
      this.setData({
        profile: Object.assign({}, this.data.profile, { avatarSrc: "" })
      });
      return Promise.resolve();
    }

    if (/^https?:\/\//.test(avatar)) {
      this.setData({
        profile: Object.assign({}, this.data.profile, { avatarSrc: avatar })
      });
      return Promise.resolve();
    }

    return new Promise(resolve => {
      try {
        wx.cloud.getTempFileURL({
          fileList: [avatar],
          success: res => {
            const list = res && res.fileList;
            const file = list && list[0];
            const url =
              file && file.status === 0 && file.tempFileURL
                ? file.tempFileURL
                : "";
            this.setData({
              profile: Object.assign({}, this.data.profile, { avatarSrc: url })
            });
            resolve();
          },
          fail: () => {
            this.setData({
              profile: Object.assign({}, this.data.profile, { avatarSrc: "" })
            });
            resolve();
          }
        });
      } catch (error) {
        this.setData({
          profile: Object.assign({}, this.data.profile, { avatarSrc: "" })
        });
        resolve();
      }
    });
  },

  handleQueryUserInfoTap() {
    wx.navigateTo({
      url: "/pages/userInfo/userInfo",
      fail: () => {
        wx.showToast({
          title: STRINGS.toastProfileFailed,
          icon: "none"
        });
      }
    });
  },

  handleQueryActivitiesOrganizedTap() {
    wx.navigateTo({
      url: "/pages/activityOrganized/activityOrganized",
      fail: () => {
        wx.showToast({
          title: STRINGS.toastNavigateFailed,
          icon: "none"
        });
      }
    });
  },

  handleQueryActivitiesParticipatedTap() {
    wx.navigateTo({
      url: "/pages/activityParticipated/activityParticipated",
      fail: () => {
        wx.showToast({
          title: STRINGS.toastNavigateFailed,
          icon: "none"
        });
      }
    });
  },

  handleActivityCardTap(event) {
    const dataset =
      event && event.currentTarget ? event.currentTarget.dataset : null;
    const activityID = dataset ? dataset.id : "";
    if (!activityID) return;
    wx.navigateTo({
      url: `/pages/activity-detail/activity-detail?activityID=${activityID}`,
      fail: () => {
        wx.showToast({
          title: STRINGS.toastNavigateFailed,
          icon: "none"
        });
      }
    });
  },

  handleSettingsTap(event) {
    const dataset =
      event && event.currentTarget ? event.currentTarget.dataset : null;
    const key = dataset ? dataset.key : "";
    if (!key) return;

    if (key === "privacyPolicy") {
      wx.navigateTo({
        url: "/pages/privacyPolicy/privacyPolicy",
        fail: () => {
          wx.showToast({
            title: STRINGS.toastNavigateFailed,
            icon: "none"
          });
        }
      });
    }
  },
});
